# -*- coding:utf-8 -*-
__author__ = 'Dragon Sun'
__date__ = '2025-07-02 20:28:44'

import datetime
import json
from typing import Any, Union, Callable, Optional

from websocket import WebSocket

from src.conf.conf import G_API配置, G_应用配置
from src.wss.ds_wss_okxv5_base import DSOKXv5WebSocketBase


class DS_OKXv5_WSS_公共频道类(DSOKXv5WebSocketBase):

    def __init__(self):
        super().__init__(url=G_API配置.wss_public)

        # 回调
        self.最新价格更新回调: Optional[Callable[[DS_OKXv5_WSS_公共频道类, float], None]] = None
        self.标记价格更新回调: Optional[Callable[[DS_OKXv5_WSS_公共频道类, float], None]] = None

    def _on_open(self, ws: WebSocket):
        super()._on_open(ws)

        self._订阅_tickers()
        self._订阅_标记价格()

    def _on_message(self, ws: WebSocket, message: Any):
        最新价格 = self._解析最新价格(message)
        if 最新价格 is not None:
            self._最新价格更新处理(最新价格=最新价格)

        标记价格 = self._解析标记价格(message)
        if 标记价格 is not None:
            self._标记价格更新处理(标记价格=标记价格)

    def _订阅_tickers(self):
        param1 = {
            'channel': 'tickers',
            'instId': G_应用配置.标的,
        }
        params = [param1]
        self.订阅(params=params)

    def _订阅_标记价格(self):
        param1 = {
            'channel': 'mark-price',
            'instId': G_应用配置.标的,
        }
        params = [param1]
        self.订阅(params=params)

    def _最新价格更新处理(self, 最新价格: float):
        if self.最新价格更新回调:
            self.最新价格更新回调(self, 最新价格)

    def _标记价格更新处理(self, 标记价格: float):
        if self.标记价格更新回调:
            self.标记价格更新回调(self, 标记价格)

    @staticmethod
    def _解析最新价格(message: str) -> Union[float, None]:
        """
            {
                "arg": {
                    "channel": "tickers",
                    "instId": "BTC-USDT-SWAP"
                },
                "data": [{
                    "instType": "SWAP",
                    "instId": "BTC-USDT-SWAP",
                    "last": "109146.9",
                    "lastSz": "223.46",
                    "askPx": "109147",
                    "askSz": "0.01",
                    "bidPx": "109146.9",
                    "bidSz": "2178.35",
                    "open24h": "106137.6",
                    "high24h": "110359.9",
                    "low24h": "104925.1",
                    "sodUtc0": "105645.5",
                    "sodUtc8": "108699.8",
                    "volCcy24h": "1602408.0575",
                    "vol24h": "160240805.75",
                    "ts": "1751473800764"
                }]
            }
        """
        # noinspection PyBroadException
        try:
            d: dict = json.loads(message)
            if (d['arg']['channel'] == 'tickers') and (d['arg']['instId'] == G_应用配置.标的):
                last = float(d['data'][0]['last'])
                return last
            return None
        except Exception:
            return None

    @staticmethod
    def _解析标记价格(message: str) -> Union[float, None]:
        """
            {
                "arg": {
                    "channel": "mark-price",
                    "instId": "BTC-USDT-SWAP"
                },
                "data": [{
                    "instId": "BTC-USDT-SWAP",
                    "instType": "SWAP",
                    "markPx": "108849.6",
                    "ts": "1751526844659"
                }]
            }
        """
        # noinspection PyBroadException
        try:
            d: dict = json.loads(message)
            if (d['arg']['channel'] == 'mark-price') and (d['arg']['instId'] == G_应用配置.标的):
                mark = float(d['data'][0]['markPx'])
                return mark
            return None
        except Exception:
            return None


if __name__ == '__main__':
    ws_obj = DS_OKXv5_WSS_公共频道类()
    ws_obj.最新价格更新回调 = lambda _, 最新价格: print(f'{datetime.datetime.now()} 最新价格：{最新价格}')
    ws_obj.标记价格更新回调 = lambda _, 标记价格: print(f'{datetime.datetime.now()} 标记价格：{标记价格}')
    ws_obj.run()
